package com.ttc.group2.videochat.helper;

import java.util.Collection;
import java.util.List;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;

import com.quickblox.chat.QBRoster;
import com.quickblox.chat.listeners.QBRosterListener;
import com.quickblox.chat.model.QBPresence;
import com.quickblox.chat.model.QBRosterEntry;
import com.quickblox.core.exception.QBResponseException;
import com.quickblox.core.request.QBPagedRequestBuilder;
import com.quickblox.users.QBUsers;
import com.quickblox.users.model.QBUser;
import com.ttc.group2.videochat.database.DbHelper;
import com.ttc.group2.videochat.model.Friend;
import com.ttc.group2.videochat.model.User;
import com.ttc.group2.videochat.utils.ErrorUtils;
import com.ttc.group2.videochat.utils.FriendUtils;

public class QBFriendListHelper extends BaseHelper {

	public static final String RELATION_STATUS_NONE = "none";
	public static final String RELATION_STATUS_TO = "to";
	public static final String RELATION_STATUS_FROM = "from";
	public static final String RELATION_STATUS_BOTH = "both";
	public static final String RELATION_STATUS_REMOVE = "remove";
	public static final String RELATION_STATUS_ALL_USERS = "all_users";
	public static final int VALUE_RELATION_STATUS_ALL_USERS = 10;
	private static final String TAG = QBFriendListHelper.class.getSimpleName();
	private static final String PRESENCE_CHANGE_ERROR = "Presence change error: could not find friend in DB by id = ";
	private static final String ENTRIES_UPDATING_ERROR = "Failed to update friends list";
	private static final String ENTRIES_DELETED_ERROR = "Failed to delete friends";

	private static final int FIRST_PAGE = 1;
	// Default value equals 0, bigger value allows to prevent overwriting of
	// presence that contains status
	// with presence that is sent on login by default
	private static final int STATUS_PRESENCE_PRIORITY = 1;

	private QBRestHelper restHelper;
	private QBRoster roster;

	public QBFriendListHelper(Context context) {
		super(context);
	}

	public void init() {
		restHelper = new QBRestHelper(mContext);
		roster.setSubscriptionMode(QBRoster.SubscriptionMode.mutual);
		roster.addRosterListener(new RosterListener());
	}

	private void updateFriends(Collection<Integer> userIdsList)
			throws QBResponseException {
		for (Integer userId : userIdsList) {
			updateFriend(userId);
		}
	}

	private void updateFriend(int userId) throws QBResponseException {
		QBRosterEntry rosterEntry = roster.getEntry(userId);

		User newUser = restHelper.loadUser(userId);

		if (newUser == null) {
			return;
		}

		Friend friend = FriendUtils.createFriend(rosterEntry);

		newUser.setOnline(isFriendOnline(roster.getPresence(userId)));

		fillUserOnlineStatus(newUser);
	}

	private List<QBUser> loadUsers(Collection<Integer> userIds)
			throws QBResponseException {
		QBPagedRequestBuilder requestBuilder = new QBPagedRequestBuilder();
		requestBuilder.setPage(FIRST_PAGE);
		requestBuilder.setPerPage(userIds.size());

		Bundle params = new Bundle();
		return QBUsers.getUsersByIDs(userIds, requestBuilder, params);
	}

	private void fillUsersWithRosterData(List<User> usersList) {
		for (User user : usersList) {
			fillUserOnlineStatus(user);
		}
	}

	private void fillUserOnlineStatus(User user) {
		if (roster != null) {
			QBPresence presence = roster.getPresence(user.getUserId());
			fillUserOnlineStatus(user, presence);
		}
	}

	private void fillUserOnlineStatus(User user, QBPresence presence) {
		if (isFriendOnline(presence)) {
			user.setOnline(true);
		} else {
			user.setOnline(false);
		}
	}

	private boolean isFriendOnline(QBPresence presence) {
		return QBPresence.Type.online.equals(presence.getType());
	}

	private void deleteFriend(int userId) {
		DbHelper.getInstance(mContext).deleteUser(userId);
	}

	private void deleteFriends(Collection<Integer> userIdsList)
			throws QBResponseException {
		for (Integer userId : userIdsList) {
			deleteFriend(userId);
		}
	}

	private class RosterListener implements QBRosterListener {

		@Override
		public void entriesDeleted(Collection<Integer> userIdsList) {
			try {
				deleteFriends(userIdsList);
			} catch (QBResponseException e) {
				Log.e(TAG, ENTRIES_DELETED_ERROR, e);
			}
		}

		@Override
		public void entriesAdded(Collection<Integer> userIdsList) {
		}

		@Override
		public void entriesUpdated(Collection<Integer> userIdsList) {
			try {
				updateFriends(userIdsList);
			} catch (QBResponseException e) {
				Log.e(TAG, ENTRIES_UPDATING_ERROR, e);
			}
		}

		@Override
		public void presenceChanged(QBPresence presence) {
			User user = DbHelper.getInstance(mContext).getUserById(
					presence.getUserId());
			if (user == null) {
				ErrorUtils.logError(TAG,
						PRESENCE_CHANGE_ERROR + presence.getUserId());
			} else {
				fillUserOnlineStatus(user, presence);
				DbHelper.getInstance(mContext).saveUser(user);
			}
		}
	}

}